﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualBasic.FileIO;

namespace MvcApplication1.CsvParser
{
	public enum FileFormat
	{
		Delimited,
		FixedWidth
	}

	internal static class FileFormatExtensions
	{
		public static FieldType ToVbFieldType(this FileFormat value)
		{
			switch (value)
			{
				case FileFormat.Delimited:
					return FieldType.Delimited;
				case FileFormat.FixedWidth:
					return FieldType.FixedWidth;
				default:
					throw new ArgumentException("Unknown format type", "value");
			}
		}
	}

	public class CsvFile
	{
		// Redfine this so consumers don't have to take a reference on MS.VB
		private TextReader reader;
		public CsvFile(Stream s)
			: this(new StreamReader(s))
		{
		}

		public CsvFile(string filename)
			: this(new StreamReader(filename))
		{
		}

		public CsvFile(TextReader reader)
		{
			// Sensible defaults (these match TextFieldParser)
			this.FileFormat = CsvParser.FileFormat.Delimited;
			this.HasFieldsEnclosedInQuotes = true;

			this.reader = reader;
		}

		public IEnumerable<IList<string>> Parse()
		{
			TextFieldParser parser = new TextFieldParser(reader);
			parser.Delimiters = this.Delimiters;
			parser.CommentTokens = this.CommentTokens;
			parser.TextFieldType = this.FileFormat.ToVbFieldType();
			parser.HasFieldsEnclosedInQuotes = this.HasFieldsEnclosedInQuotes;
			parser.FieldWidths = this.FieldWidths;
			parser.TrimWhiteSpace = this.TrimWhiteSpace;

			List<List<string>> result = new List<List<string>>();
			while (!parser.EndOfData)
			{
				result.Add(parser.ReadFields().ToList());
			}

			return result;
		}

		/// <summary>
		/// Defines the delimiters for a text file. 
		/// </summary>
		public string[] Delimiters { get; set; }

		/// <summary>
		/// Defines comment tokens. A comment token is a string that, when placed at 
		/// the beginning of a line, indicates that the line is a comment and should 
		/// be ignored by the parser.
		/// </summary>
		public string[] CommentTokens { get; set; }

		public FileFormat FileFormat { get; set; }

		public bool HasFieldsEnclosedInQuotes { get; set; }

		public int[] FieldWidths { get; set; }

		public bool TrimWhiteSpace { get; set; }
	}
}
